package com.xbongbong.parent.data;

import com.alibaba.fastjson.JSONArray;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.parse.data.FormDataListAnalysisDataHelp;
import com.xbongbong.parent.util.CommonBusinessFieldUtil;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.form.pojo.dto.ChildProductDTO;
import com.xbongbong.pro.form.pojo.dto.EsDataDTO;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.model.IndexTypeModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/12/17 15:52
 */
@Service("formDataEsServiceImpl")
public class FormDataEsServiceImpl implements FormDataEsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(FormDataEsServiceImpl.class);

    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private IndexTypeModel indexTypeModel;

    /**
     * 根据查询条件查找对应的es数据
     *
     * @param esDataDTO 封装了查询条件的DTO
     * @author chaoxiong.lei
     * @Date 10:17 2019/2/18
     * @since v1.0
     **/
    @Override
    public PaasFormDataEsListVO getEsDataList(EsDataDTO esDataDTO) throws XbbException {
        PaasFormDataEsListVO formDataListVO;
        try {
            String corpid = esDataDTO.getCorpid();
            Integer businessType = esDataDTO.getBusinessType();
            Long formId = esDataDTO.getFormId();
            List<String> fieldList = esDataDTO.getFieldList();
            List<ConditionsEntityExt> conditionsEntityExtList = esDataDTO.getConditionsEntityExtList();

            FormDataListDTO formDataListDTO = new FormDataListDTO();
            BeanUtil.copyProperties(esDataDTO, formDataListDTO);
            formDataListDTO.setSimple(true);
            Boolean isMulti = RedundantTemplateTypeEnum.isMultiTemplate(businessType);
            PaasFormExplainEntity paasFormExplainEntity;
            if ( isMulti && formId != null ) {
                paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            } else {
                paasFormExplainEntity = paasFormExplainModel.getByBusinessType(businessType, corpid);
            }
            if ( paasFormExplainEntity == null ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
            explainList.forEach((item) -> {
                explainMap.put(item.getAttr(), item);
            });
            formDataListDTO.setExplainMap(explainMap);

            formDataListDTO.setFieldList(fieldList);
            formDataListDTO.setSaasMark(esDataDTO.getSaasMark());
            // 设置查询条件
            formDataListDTO.setConditions(conditionsEntityExtList);
            formDataListDTO.setShouldConditions(esDataDTO.getShouldConditions());
            formDataListDTO.setFormId(paasFormExplainEntity.getFormId());
            Map<String, String> sortMap = esDataDTO.getSortMap();
            if ( sortMap == null ) {
                sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                sortMap.put("field", "addTime");
                sortMap.put("sort", "asc");
                formDataListDTO.setSortMap(sortMap);
            }
            if (CollectionsUtil.isNotEmpty(fieldList)) {
                Boolean searchSubForm = false;
                for (String item : fieldList) {
                    if (item.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                        searchSubForm = true;
                    }
                }
                formDataListDTO.setSearchSubForm(searchSubForm);
            }
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
            formDataListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
            // 设置form信息
            PaasFormEntityExt paasFormEntity = new PaasFormEntityExt();
            BeanUtil.copyProperties(formDataListDTO, paasFormEntity);
            formDataListVO.setForm(paasFormEntity);
            explainList = explainHelp.handleExplain(explainList, fieldList, paasFormEntity);
            formDataListVO.setHeadList(explainList);
            if ( PlatFormEnum.WEB.getValue().equals(formDataListDTO.getPlatform()) ) {
                // web端逻辑，主要处理下关于关联数据，用户，部门数据回显的问题
                formDataListAnalysisDataHelp.analysisDataList(formDataListDTO, formDataListVO);
            } else if ( PlatFormEnum.DINGTALK.getValue().equals(formDataListDTO.getPlatform()) ) {
                // 客户端逻辑
                formDataListVO = ExplainUtil.getValueByData(formDataListVO, null, null);
            }
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            paasFormEntityExt.setBusinessName(XbbRefTypeEnum.getByCode(businessType).getName());
            String mainAttr = CommonBusinessFieldUtil.getFormEntityMainAttr(businessType);
            paasFormEntityExt.setMainAttr(mainAttr);
            formDataListVO.setForm(paasFormEntityExt);
        } catch (XbbException e) {
            LOGGER.error("paasFormDataService.getEsDataList 出错", e);
            throw e;
        } catch (Exception e) {
            LOGGER.error("paasFormDataService.getEsDataList 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        return formDataListVO;
    }


    @Override
    public PaasFormDataEsListVO getChildProductList(ChildProductDTO childProductDTO) throws XbbException {
        // 获取原父产品下的子产品
        String corpid = childProductDTO.getCorpid();
        List<Long> parentProductIds = childProductDTO.getParentProductId();
        EsDataDTO esDataDTO = new EsDataDTO();
        BeanUtil.copyProperties(childProductDTO, esDataDTO);
        esDataDTO.setCorpid(corpid);
        esDataDTO.setBusinessType(XbbRefTypeEnum.PRODUCT.getCode());
        esDataDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        esDataDTO.setFieldList(null);
        esDataDTO.setDel(0);
        esDataDTO.setPageSize(10000);
        // 导出产品数量大于1W时查询子产品会有问题 可能需要滚动查询
        esDataDTO.setFromExport(1);
        // 查询条件
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(ProductEnum.PARENT_ID.getAttr());
        conditionsEntityExt.setSymbol(ConditionEnum.IN.getSymbol());
        List<Object> idIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        idIn.addAll(parentProductIds);
        conditionsEntityExt.setValue(idIn);
        conditionsEntityExt.setFieldType(ProductEnum.PARENT_ID.getFieldType());
        esDataDTO.setConditionsEntityExtList(Collections.singletonList(conditionsEntityExt));
        // 添加should条件
        addEnableSpecifitionShouldCond4Export(childProductDTO,esDataDTO);
        // 获取数据，并且解析
        PaasFormDataEsListVO esDataList = getEsDataList(esDataDTO);
        esDataList.getPaasFormDataESList().sort(new Comparator<PaasFormDataEntityExt>() {
            @Override
            public int compare(PaasFormDataEntityExt o1, PaasFormDataEntityExt o2) {
                return o1.getId().compareTo(o2.getId());
            }
        });
        return esDataList;
    }

    /**
     * 1、如果多规格没有开启，肯定是没有规格，所以勾选了【不导出未启用规格】，可以导出产品
     * 2、如果产品开启了多规格，勾选了【不导出未启用规格】，导出时只导出已启用的规格
     * @param childProductDTO
     * @param esDataDTO
     */
    private void addEnableSpecifitionShouldCond4Export(ChildProductDTO childProductDTO,EsDataDTO esDataDTO){
        Integer enableSpecifition = childProductDTO.getExportEnableSpecifition();
        if (Objects.isNull(enableSpecifition) || Objects.equals(enableSpecifition,0)){
            return;
        }
        List<List<ConditionsEntityExt>> shouldConditions = esDataDTO.getShouldConditions();
        // 没有开启多规格
        ConditionsEntityExt speCond = new ConditionsEntityExt();
        speCond.setAttr(ProductEnum.SPECIFICATION.getAttr());
        speCond.setSymbol(ConditionEnum.EQUAL.getSymbol());
        speCond.setValue(Arrays.asList(0));
        speCond.setFieldType(ProductEnum.SPECIFICATION.getFieldType());
        shouldConditions.add(Collections.singletonList(speCond));
        
        // 多规格开启 && 规格开启
        ArrayList<ConditionsEntityExt> speAndSku = new ArrayList<>();
        ConditionsEntityExt spe = new ConditionsEntityExt();
        spe.setAttr(ProductEnum.SPECIFICATION.getAttr());
        spe.setSymbol(ConditionEnum.EQUAL.getSymbol());
        spe.setValue(Arrays.asList(1));
        spe.setFieldType(ProductEnum.SPECIFICATION.getFieldType());
        speAndSku.add(spe);

        ConditionsEntityExt sku = new ConditionsEntityExt();
        sku.setAttr(ProductEnum.ENABLE_SKU.getAttr());
        sku.setSymbol(ConditionEnum.EQUAL.getSymbol());
        sku.setValue(Arrays.asList(1));
        sku.setFieldType(ProductEnum.ENABLE_SKU.getFieldType());
        speAndSku.add(sku);
        shouldConditions.add(speAndSku);
    }
}
